package me.yricky.mayu.ui.tasks.taskui.seqali

import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.Button
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.NavigateBefore
import androidx.compose.material.icons.rounded.NavigateNext
import androidx.compose.material.icons.rounded.PlayArrow
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch
import me.yricky.mayu.ui.*
import me.yricky.mayu.ui.fasta.SeqChar
import me.yricky.mayu.ui.misc.emptyPainter
import me.yricky.mayu.ui.misc.symBolMap
import me.yricky.mayu.ui.tasks.taskui.Finished
import me.yricky.mayu.ui.tasks.taskui.Idle
import me.yricky.mayu.ui.tasks.taskui.Running
import me.yricky.mayu.ui.tasks.taskui.Terminate

/**
 * @author Yricky
 * @date 2022/4/25
 */

val SeqAlignmentTask.Idle: Idle
    get() = object : Idle {
    @Composable
    override fun Page(modifier: Modifier) {
        Column {
            Button({
                scope.launch {
                    status = Running
                    try {
                        session.run()
                    }catch (e:Throwable){
                        e.printStackTrace()
                        status = Terminate(e)
                    }
                }
            }, Modifier.fillMaxWidth()){
                Icon(Icons.Rounded.PlayArrow,"")
                Text("点击运行(预计内存占用：约${memConsumeMB}MB)")
            }
        }


    }
}

fun SeqAlignmentTask.Terminate(e:Throwable): Terminate {
    return object : Terminate {
        @Composable
        override fun Page(modifier: Modifier) {
            Column {
                Button({
                    scope.launch {
                        status = Running
                        session.run()
                    }
                }) {
                    Text("rerun")
                }
                Text(e.stackTraceToString())
            }

        }
    }
}

val SeqAlignmentTask.Running: Running
    get() = object : Running {
    override val progress: State<Float> = session.progress

    @Composable
    override fun Page(modifier: Modifier) {  }
}

val SeqAlignmentTask.Finished: Finished
    get()= object : Finished {
    @Composable
    override fun Page(modifier: Modifier) {
        val list by resultList.collectAsState()
        val firstRange by firstRange.collectAsState()
        val secondRange by secondRange.collectAsState()
        Column(modifier) {
            Row {
                Button({
                    scope.launch {
                        status = Running
                        session.run()
                    }
                }) {
                    Text("rerun")
                }
                if (list.isNotEmpty()) {
                    Text("发现最佳匹配子序列($firstRange)和($secondRange)，分值为${session.result.first}，理论最佳分值为${session.bestScore}，匹配度${(session.result.first.toFloat() * 100 / session.bestScore)}%，用时${session.lastTimeConsumeMillis/1000f}s")
                }
            }
            Row(verticalAlignment = Alignment.CenterVertically) {
                val state = rememberLazyListState()
                val scope = rememberCoroutineScope()
                Icon(Icons.Rounded.NavigateBefore, "",
                    Modifier.width(36.dp).height(IntrinsicSize.Max).clickable {
                    scope.launch {
                        state.animateScrollToItem(state.previousPageIndex())
                    }
                })
                var location by remember { mutableStateOf(Location4(0)) }
                LazyRowWithScrollBar(
                    Modifier.fillMaxHeight().weight(1f).pointLocation4 { location = it },
                    state = state) {
                    items(list) {
                        Column(Modifier.padding(1.dp, 8.dp).width(20.dp)) {
                            val char1 = seq1.seq.getOrNull(it.first) ?: ' '
                            val char2 = seq2.seq.getOrNull(it.second) ?: ' '
                            SeqChar(
                                Modifier.padding(1.dp).size(24.dp,36.dp),
                                seq = seq1,
                                c = char1,
                                popupLocation = location
                            )
                            Image(
                                modifier = Modifier.padding(1.dp).size(24.dp,36.dp),
                                painter = symBolMap[if (char1 == char2) '|' else if (char1 == ' ' || char2 == ' ') ' ' else 'X'] ?: emptyPainter,
                                contentDescription = null
                            )
                            SeqChar(
                                Modifier.padding(1.dp).size(24.dp,36.dp),
                                seq = seq2,
                                c = char2,
                                popupLocation = location
                            )
                        }
                    }
                }
                Icon(Icons.Rounded.NavigateNext, "", Modifier.width(36.dp).height(IntrinsicSize.Max).clickable {
                    scope.launch {
                        state.animateScrollToItem(state.nextPageIndex())
                    }
                })
            }
        }

    }
}